﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;

namespace MineSweeperChallenge
{
    public class SingleThreadedGameRunner : IGameRunner
    {
        public void RunGame(ISweeper pSweeper, int pTimes, int pWidth, int pHeight, int pMines, Action<string> pCallbackAction, ProgressBar pProgressBar)
        {
            BackgroundWorker lBackgroundWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };

            int lWins = 0;
            int lExceptions = 0;
            double[] lExecutionTimes = new double[pTimes];
            lBackgroundWorker.DoWork += (sender, e) =>
            {
                for (int i = 0; i < pTimes; i++)
                {
                    lBackgroundWorker.ReportProgress(Convert.ToInt32((Convert.ToDouble(i+1) / pTimes) * 100));
                    Game lGame = new Game(pSweeper, pWidth, pHeight, pMines);
                    lGame.Initialize();
                    Game.Result lResult = lGame.Play();
                    if (lResult.Win) lWins++;
                    if (lResult.HadException) lExceptions++;
                    lExecutionTimes[i] = lResult.TimeTakenMilliseconds;
                    Thread.Sleep(1);
                }
                e.Result = string.Format("Times played: {0}\nTimes won: {1}\nAverage execution time (milliseconds): {2}\nTimes ran with errors: {3}", pTimes, lWins, lExecutionTimes.Average(), lExceptions);
            };
            lBackgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if (pCallbackAction != null) pCallbackAction((string) e.Result);
            };

            lBackgroundWorker.ProgressChanged += (sender, e) =>
            {
                pProgressBar.Dispatcher.BeginInvoke(DispatcherPriority.Render, (SendOrPostCallback)delegate { pProgressBar.SetValue(ProgressBar.ValueProperty, e.ProgressPercentage / 100d); }, null);
            };

            lBackgroundWorker.RunWorkerAsync();
        }
    }
}
